include(CheckCXXCompilerFlag)
include(CheckCXXSourceCompiles)

# Replaces the slash character in flags to enable use of MSVC compiler arguments in variable names
macro(cflag_name_to_var_name outvar prefix flag)
    string(REPLACE "/" "_" _flag_clean "${flag}")
    set(${outvar} "${prefix}_${_flag_clean}_SUPPORTED")
    unset(_flag_clean)
endmacro()

macro(enable_cflags_if_supported)
    foreach(flag ${ARGN})
        cflag_name_to_var_name(_supported_var CXXFLAG ${flag})
        check_cxx_compiler_flag("${flag}" ${_supported_var})
        if(${_supported_var})
            add_compile_options("${flag}")
        endif()
        unset(_supported_var)
    endforeach()
endmacro()

macro(enable_linker_flags_if_supported)
    set(_old_CMAKE_REQUIRED_LINK_OPTIONS "${CMAKE_REQUIRED_LINK_OPTIONS}")
    foreach(flag ${ARGN})
        set(CMAKE_REQUIRED_LINK_OPTIONS "${flag}")
        cflag_name_to_var_name(_supported_var LDCFLAG ${flag})
        check_cxx_source_compiles("int main(){return 0;}" ${_supported_var})
        if(${_supported_var})
            add_link_options(${flag})
        else()
            set(CMAKE_REQUIRED_LINK_OPTIONS "LINKER:${flag}")
            cflag_name_to_var_name(_supported_linker_var LDCFLAG_LINKER ${flag})
            check_cxx_source_compiles("int main(){return 0;}" ${_supported_linker_var})
            if(${_supported_linker_var})
                add_link_options(LINKER:${flag})
            endif()
            unset(_supported_linker_var)
        endif()
        unset(_supported_var)
    endforeach()
    set(CMAKE_REQUIRED_LINK_OPTIONS "${_old_CMAKE_REQUIRED_LINK_OPTIONS}")
endmacro()

macro(enable_target_linker_flags_if_supported target access)
    set(_old_CMAKE_REQUIRED_LINK_OPTIONS "${CMAKE_REQUIRED_LINK_OPTIONS}")
    foreach(flag ${ARGN})
        set(CMAKE_REQUIRED_LINK_OPTIONS "${flag}")
        cflag_name_to_var_name(_supported_var LDCFLAG ${flag})
        check_cxx_source_compiles("int main(){return 0;}" ${_supported_var})
        if(${_supported_var})
            target_link_options(${target} ${access} ${flag})
        else()
            set(CMAKE_REQUIRED_LINK_OPTIONS "LINKER:${flag}")
            cflag_name_to_var_name(_supported_linker_var LDCFLAG_LINKER ${flag})
            check_cxx_source_compiles("int main(){return 0;}" ${_supported_linker_var})
            if(${_supported_linker_var})
                target_link_options(${target} ${access} LINKER:${flag})
            endif()
            unset(_supported_linker_var)
        endif()
        unset(_supported_var)
    endforeach()
    set(CMAKE_REQUIRED_LINK_OPTIONS "${_old_CMAKE_REQUIRED_LINK_OPTIONS}")
endmacro()
